package com.mangix;

import com.mangix.conf.MangixConfig;
import com.mangix.core.MangixMonitor;
import com.mangix.core.MangixNode;
import com.mangix.http.MangixServer;
import com.mangix.utils.MangixUtils;
import org.apache.commons.lang.StringUtils;

/**
 * Created by xiaolu on 11/14/14.
 */
public class MangixBuilder {

    public static void run(String strKnownNode, String strMonitor, String strObservation) {
        try {
            // Initialize the config instance from the config file.
            MangixConfig config = MangixConfig.getInstance();
            String hostname = config.getHostName();
            // If there is a monitor, start it.
            MangixMonitor monitor = null;
            if (config.isMonitor()) {
                // If there is a monitor in this physical node.
                monitor = new MangixMonitor(config);
                monitor.start();
                if (StringUtils.isNotBlank(strMonitor)) {
                    // Set the superior of this monitor.
                    String[] monitorInfo = strMonitor.split(":");
                    MangixMonitor superior = new MangixMonitor(monitorInfo[0], Integer.parseInt(monitorInfo[1]));
                    monitor.setMonitor(superior);
                }
                if (StringUtils.isNotBlank(strObservation)) {
                    // Add a observation node to this monitor.
                    String[] observationNodeInfo = strObservation.split(":");
                    monitor.addObservation(observationNodeInfo[0], Integer.parseInt(observationNodeInfo[1]));
                }
            } else {
                // If a monitor is specified.
                if (StringUtils.isNotBlank(strMonitor)) {
                    // Set the superior of this monitor.
                    String[] monitorInfo = strMonitor.split(":");
                    monitor = new MangixMonitor(monitorInfo[0], Integer.parseInt(monitorInfo[1]));
                }
            }

            int[] ports = config.getPorts();
            // Check whether the id of each node is unique.
            int M = config.getM();
            long [] ids = new long[ports.length];
            for (int i = 0; i < ports.length; i ++ ) {
                ids[i] = MangixUtils.hash(hostname + ":" + ports[i], M);
                for (int j = 0; j < i; j ++ ) {
                    if (ids[i] == ids[j]) {
                        System.out.println("The port " + ports[j] + " and port " + ports[i] + " have the same id: " + ids[i] + ", please change one of them." );
                        System.exit(-1);
                    }
                }
            }

            // Make sure this is called before any createNode function!
            MangixNode.createLocalNodes(config);
            // Start local mangix nodes one bye one.
            MangixNode knownNode = null;
            if (StringUtils.isNotBlank(strKnownNode)) {
                String[] knownNodeInfo = strKnownNode.split(":");
                knownNode = MangixNode.createNode(knownNodeInfo[0], Integer.parseInt(knownNodeInfo[1]));
            }
            for (int port : ports) {
                MangixNode node = MangixNode.createNode(hostname, port);
                // Start mangix.Mangix Http Server.
                MangixServer httpServer = null;
                if (knownNode != null) {
                    httpServer = new MangixServer(node, knownNode);
                } else {
                    httpServer = new MangixServer(node);
                    knownNode = node;
                }
                if (monitor != null) {
                    node.setMonitor(monitor);
                }
                httpServer.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
}
